package com.gas.gm.pdu.session;

import java.io.IOException;

import org.apache.log4j.Logger;

import com.gas.gm.pdu.DataProcessor;
import com.gas.gm.pdu.DataProcessorFactory;
import com.logica.smpp.Connection;
import com.logica.smpp.Data;
import com.logica.smpp.TCPIPConnection;

public class GasGmSessionListener implements Runnable{
	
	private static final Logger logger=Logger.getLogger(GasGmSessionListener.class);
	
	private Connection serverCon;
	private int port;
	private long acceptTimeout=Data.ACCEPT_TIMEOUT;
	private DataProcessorFactory processorFactory;
	private boolean keepReceiving = true;
    private boolean isReceiving = false;
    private boolean asynchronous = false;
    
    public GasGmSessionListener(int port){
    	this.port=port;
    }
    public GasGmSessionListener(int port,boolean async){
    	this.port=port;
    	this.asynchronous=async;
    }

	public void run() {
		//logger.info("run of SMSCListener on port: "+port);
		 isReceiving = true;
	        try {
	            while (keepReceiving) {
	                listen();
	                Thread.yield();
	            }
	        } finally {
	            isReceiving = false;
	        }
	}
	
	public synchronized void start() throws IOException
	{
		//logger.info("listener starting at port.."+port);
		if(!isReceiving){
			serverCon=new TCPIPConnection(port);
			serverCon.setReceiveTimeout(getAcceptTimeout());
			serverCon.open();
			keepReceiving=true;
			if(asynchronous){
				logger.info("listener beda thread");
				Thread server=new Thread(this);
				server.start();
			}else{
				logger.info("listener thread sama");
				run();
			}
		}else{
			logger.info("receiving not listening");
		}
	}
	
	public synchronized void stop() throws IOException{
		logger.info("listener stoping at port: "+port);
		keepReceiving = false;
        while (isReceiving) {
            Thread.yield();
        }
        serverCon.close();
        logger.info("listener stoped at port: "+port);
	}
	
	protected void listen(){
		//logger.info("listener listening on port: "+port);
		
		try {
			Connection connection=null;
			serverCon.setReceiveTimeout(getAcceptTimeout());
			connection=serverCon.accept();
			
			if(connection!=null)
			{
				logger.info("Listener accepted a connection on port "+port);
				GasGmSession session=new GasGmSession(connection);
				DataProcessor dataProcessor=null;
				if(processorFactory!=null){
					dataProcessor=processorFactory.createDataProcessor(session);
				}
				session.setProcessor(dataProcessor);
				Thread sessionThread=new Thread(session);
				sessionThread.start();
				logger.debug("Listener launched a session on the accepted connection.");
			}else{
				//logger.debug("no connection accepted this time");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			keepReceiving=false;
		}
	}
	
	public long getAcceptTimeout() {
		return acceptTimeout;
	}
	public DataProcessorFactory getProcessorFactory() {
		return processorFactory;
	}
	
	public void setProcessorFactory(DataProcessorFactory processorFactory) {
		this.processorFactory = processorFactory;
	}
	public void setAcceptTimeout(long acceptTimeout) {
		this.acceptTimeout = acceptTimeout;
	}
	
	

}
